package com.apexedu.biz.service.impl;

import com.apexedu.biz.action.BusinessTabButAction;
import com.apexedu.framework.service.impl.AbstractBaseServiceSupport;
import com.apexedu.framework.util.DBUtil;
import com.apexedu.framework.util.Pager;
import com.apexedu.framework.util.SeqFactory;
import com.apexedu.identity.entity.TSysRole;
import com.apexedu.identity.entity.TSysRoleMenu;
import com.apexedu.identity.entity.TSysRoleMenuButton;
import com.apexedu.sys.SysConstant;
import com.apexedu.sys.entity.ApplicationEnum;
import com.apexedu.sys.util.BusinessLogUtil;
import com.apexedu.util.StringUtil;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * 业务系统IFRAME页面的操作角色
 * User: houcong
 * Date: 14-4-17
 * Time: 下午3:00
 * To change this template use File | Settings | File Templates.
 */
@Service("businessTabButService")
public class BusinessTabButServiceImpl extends AbstractBaseServiceSupport {

    //点击角色进入唯一查
    @Override
    public void load(Object o) throws Exception {
        // query a role
        BusinessTabButAction action = (BusinessTabButAction) o;
        //需要判断wid
        String roleid = action.getParameter("wid");
        String hql = "from TSysRole where roleid = ?";
        TSysRole role = (TSysRole) getBaseDao().findFieldValue(hql, roleid);
        action.setTsysRole(role);
        // 下面取得权限菜单
        // action.setParameter("menues", queryRoleMenuid(roleid));
        setMenuAndButton(action, roleid);

        String type = action.getParameter("type"); //类型 menu为权限菜单 user为用户角色

        action.setParameter("type", type);
    }

    public void openCreate(Object myaction) throws Exception {
        BusinessTabButAction action = (BusinessTabButAction) myaction;
        //获取 ApplicationEnum 的 集合
        List<ApplicationEnum> appRegList = queryAllMenu();
        String no = (String) action.getSession().getAttribute("no");
        // 获取二级菜单名
        action.setListMenuDepth2(appRegList);
        if (!appRegList.isEmpty() && appRegList.get(Integer.parseInt(no)) != null
                && StringUtil.isNotBlank(appRegList.get(Integer.parseInt(no)).getId())) {
            action.setParameter("defaultMenuid", appRegList.get(Integer.parseInt(no)).getId());
        }
        String type = action.getParameter("type"); //类型 menu为权限菜单 user为用户角色
        action.setParameter("type", type);
    }

    @Override
    public List<?> list(Object o, Pager pager) throws Exception {
        BusinessTabButAction action = (BusinessTabButAction) o;
        //获取 ApplicationEnum 的 集合
        List<ApplicationEnum> appRegList = queryAllMenu();
        TSysRole tsysRole = action.getTsysRole();
        List<Object> params = new LinkedList<Object>();
        String hql = "from TSysRole where 1=1";
        if (tsysRole != null) {
            if (tsysRole.getRoleid() != null && !tsysRole.getRoleid().equals("")) {
                hql += " and roleid = ?";
                params.add(tsysRole.getRoleid());
            }
            if (tsysRole.getRolename() != null && !tsysRole.getRolename().equals("")) {
                hql += " and rolename like ?";
                params.add(" %" + tsysRole.getRolename() + "%");
            }
            if (tsysRole.getState() != null && !tsysRole.getState().equals("")) {
                hql += " and state = ?";
                params.add(tsysRole.getState());
            }
        }

        String appid = action.getAppid(); //业务系统id
        //第一次默认为appRegList集合的第一位
        if (StringUtil.isBlank(appid)) {
            appid = appRegList.get(0).getId();
        }
        //保存tab页appRegList集合的下标
        String no = null;

        for (int i = 0; i < appRegList.size(); i++) {
            String appReg = appRegList.get(i).getId();
            if (appReg.equals(appid)) {
                no = String.valueOf(i);
                break;
            }
        }
        action.getSession().setAttribute("no", no);
        hql += " and belongtoapp = '" + appid + "'";
        int rownum = (int) getBaseDao().count("select count(*) " + hql,params.toArray());  //该业务系统下有多少条角色
        pager.setTotalRows(rownum);
        pager.setEachPageRows(10);
        action.setRownum(rownum);
        hql = hql + " order by roleid";
        List<TSysRole> tsysRoles = getBaseDao().findPageByHql(hql, pager,params.toArray());
        action.setAppid(appid);

        String type = action.getParameter("type"); //类型 menu为权限菜单 user为用户角色
        action.setParameter("type", type);
        return tsysRoles;
    }

    /**
     * 删除角色需要同时删除关系表中的角色数据：菜单与角色关联表、组与角色关联表 事务的控制交给spring配置
     */
    public boolean remove(Object myaction) throws Exception {
        BusinessTabButAction action = (BusinessTabButAction) myaction;
        String ids = action.getParameter("wid");
        removeRoleMenuButton(ids);
        removeRoleMenu(ids);
        removeRoleUser(ids);
        boolean deleteSuccess = getBaseDao().deleteAll("TSysRole", "roleid", "=", ids);
        if (deleteSuccess) {
            BusinessLogUtil.log(action.getLoginuser().getUserloginid(), SysConstant.CZDX_T_SYS_ROLE,
                    SysConstant.LOG_ACTION_DEL, action.getRequest().getRemoteAddr());
        }
        return deleteSuccess;
    }

    private boolean removeRoleMenu(String ids) throws Exception {
        return getBaseDao().deleteAll("TSysRoleMenu", "roleid", "=", ids);
    }

    private boolean removeRoleUser(String ids) throws Exception {
        return getBaseDao().deleteAll("TSysUserRole", "roleid", "=", ids);
    }

    private boolean removeRoleMenuButton(String ids) throws Exception {
        return getBaseDao().deleteAll("TSysRoleMenuButton", "roleid", "=", ids);
    }


    public void saveOrUpdate(Object myaction) throws Exception {
        BusinessTabButAction action = (BusinessTabButAction) myaction;
        String type = action.getType(); //类型 menu为权限菜单 user为用户角色
        TSysRole tsysRole = action.getTsysRole();
        //获取选择的业务
        String no = (String) action.getSession().getAttribute("no");
        //获取 ApplicationEnum 的 集合
        List<ApplicationEnum> appRegList = queryAllMenu();
        if (tsysRole == null) {

            action.addActionError("保存失败[ 被保存的对象为null ]");
        } else {
            //获取Belongtoapp的编号
            ApplicationEnum ApplicationEnum = appRegList.get(Integer.parseInt(no));

            if (StringUtil.isBlank(tsysRole.getRoleid())) {
                /** 20140418 houcong 修改 不同的业务系统可以添加同名的角色**/
                boolean isRoleNameExist = getBaseDao().count("select count(*) as c from TSysRole where roleName = ? and BELONGTOAPP = ?",
                        tsysRole.getRolename().trim(), ApplicationEnum.getId()) > 0;
                if (isRoleNameExist) {
                    throw new Exception("角色名重复!");
                }
                tsysRole.setRoleid(SeqFactory.getNewSequenceAlone());
                tsysRole.setBizcode(tsysRole.getRoleid()); // 如果其他外部系统接入，此号就和roleid不一样了。
//              tsysRole.setBelongtoapp(Const.AuCenterAccessEnterCode);

                tsysRole.setBelongtoapp(ApplicationEnum.getId());
                getBaseDao().save(tsysRole);
                // 保存角色菜单
                saveOrUpdateMenu(action, tsysRole.getRoleid(), SysConstant.CZLX_XZ);
                // 保存角色菜单按钮
                saveOrUpdateMenuButton(action, tsysRole.getRoleid(), SysConstant.CZLX_XZ);
                BusinessLogUtil.log(action.getLoginuser().getUserloginid(), SysConstant.CZDX_T_SYS_ROLE,
                        SysConstant.LOG_ACTION_SAVE, action.getRequest().getRemoteAddr());
            } else {
                // 更新角色菜单
                saveOrUpdateMenu(action, tsysRole.getRoleid(), SysConstant.CZLX_XG);
                // 更新角色菜单按钮
                saveOrUpdateMenuButton(action, tsysRole.getRoleid(), SysConstant.CZLX_XG);
                getBaseDao().updateNotNull(tsysRole);
                BusinessLogUtil.log(action.getLoginuser().getUserloginid(), SysConstant.CZDX_T_SYS_ROLE,
                        SysConstant.LOG_ACTION_UPDATE, action.getRequest().getRemoteAddr());
            }
        }

        //通过no 获取对应的 业务的名称
        ApplicationEnum ApplicationEnum = appRegList.get(Integer.parseInt(no));
        action.setParameter("appname", ApplicationEnum.getCaption());

        // 获取二级菜单名
        action.setListMenuDepth2(appRegList);
        /**20140418 houcong 修改 新增后 资源的绑定功能**/
        if (!appRegList.isEmpty() && appRegList.get(Integer.parseInt(no)) != null
                && StringUtil.isNotBlank(appRegList.get(Integer.parseInt(no)).getId())) {
            action.setParameter("defaultMenuid", appRegList.get(Integer.parseInt(no)).getId());
        }
        action.setParameter("type", type);
    }

    /**
     * 获取二级菜单名 及 角色菜单信息 角色菜单按钮信息
     *
     * @param myaction
     * @param roleid
     * @throws Exception
     */
    private void setMenuAndButton(Object myaction, String roleid) throws Exception {
        BusinessTabButAction action = (BusinessTabButAction) myaction;
        //获取 ApplicationEnum 的 集合
        List<ApplicationEnum> appRegList = queryAllMenu();
        // 获取二级菜单名
        action.setListMenuDepth2(appRegList);
        String no = (String) action.getSession().getAttribute("no");
        if (!appRegList.isEmpty() && appRegList.get(Integer.parseInt(no)) != null
                && StringUtil.isNotBlank(appRegList.get(Integer.parseInt(no)).getId())) {
            action.setParameter("defaultMenuid", appRegList.get(Integer.parseInt(no)).getId());
        }
        String hqlb = "from TSysRoleMenuButton a where 1=1";
        String hqlm = "from TSysRoleMenu a where 1=1";
        String hql = "";
        if (StringUtil.isNotBlank(roleid)) {
            hql += " and roleid = '" + roleid + "'";
            action.setParameter("roleid", roleid);
            StringBuffer menuButtons = new StringBuffer();
            List<TSysRoleMenuButton> listMenuButtons = getBaseDao().findByHql(hqlb + hql);
            if (!listMenuButtons.isEmpty()) {
                for (int i = 0; i < listMenuButtons.size(); i++) {
                    TSysRoleMenuButton o = listMenuButtons.get(i);
                    if (null != o)
                        menuButtons.append(o.getMenuid()).append("_").append(o.getButtonid());
                    if (i != listMenuButtons.size() - 1)
                        menuButtons.append(",");
                }
            }
            action.setParameter("menuebuttons", menuButtons.toString());
            StringBuffer menues = new StringBuffer();
            List<TSysRoleMenu> listMenues = getBaseDao().findByHql(hqlm + hql);
            if (!listMenues.isEmpty()) {
                for (int i = 0; i < listMenues.size(); i++) {
                    TSysRoleMenu o = listMenues.get(i);
                    if (null != o)
                        menues.append(o.getMenuid());
                    if (i != listMenues.size() - 1)
                        menues.append(",");
                }
            }
            action.setParameter("menues", menues.toString());
        }
    }

    /**
     * 获取二级菜单名
     *
     * @throws Exception
     */
    private List<ApplicationEnum> queryAllMenu() throws Exception {
        String sql = "select appid as id,appname as caption from T_ACCESS_APP_REG where state=1 order by ordernum desc,appid";
        List<ApplicationEnum> list = DBUtil.queryAllBeanList(sql, ApplicationEnum.class);
        return list;
    }

    /**
     * 取得此角色的权限菜单
     *
     * @param roleid
     * @return
     */
    @SuppressWarnings("unused")
    private String queryRoleMenuid(String roleid) {

        String hql = "select menuid from TSysRoleMenu where roleid=?";
        List<TSysRoleMenu> menues__ = getBaseDao().findByHql(hql, roleid);
        StringBuffer menues = new StringBuffer("");
        for (Object menu : menues__) {
            if (menu != null) {
                menues.append(menu).append(",");
            }
        }
        if (menues.length() > 0) {
            menues.delete(menues.length() - 1, menues.length());
        }
        return menues.toString();
    }

    /**
     * 保存或更新角色菜单按钮
     *
     * @param myaction
     * @param roleid   角色id
     * @param type     操作类型 保存/修改
     * @throws Exception
     */
    public void saveOrUpdateMenuButton(Object myaction, String roleid, String type) throws Exception {
        BusinessTabButAction action = (BusinessTabButAction) myaction;
        String menuebuttons = action.getParameter("menuebuttons");
        String[] curr_menuebutton = menuebuttons.split(",");
        if (SysConstant.CZLX_XZ.equals(type)) {
            List<TSysRoleMenuButton> roleMenueButtons = new ArrayList<TSysRoleMenuButton>();
            for (int i = 0; i < curr_menuebutton.length; i++) {
                if (curr_menuebutton[i].indexOf("_") != -1) {
                    TSysRoleMenuButton roleMenuButton = new TSysRoleMenuButton();
                    roleMenuButton.setId(SeqFactory.getNewSequenceAlone());
                    roleMenuButton.setRoleid(roleid);
                    roleMenuButton.setMenuid(curr_menuebutton[i].split("_")[0].trim());
                    roleMenuButton.setButtonid(curr_menuebutton[i].split("_")[1].trim());
                    roleMenueButtons.add(roleMenuButton);
                }
            }
            getBaseDao().saveAll(roleMenueButtons);
        } else {
            String hql = "select new ApplicationEnum(menuid as id,buttonid as caption) from TSysRoleMenuButton where roleid=?";
            List<ApplicationEnum> db_menuebuttons = getBaseDao().findByHql(hql, roleid);

            List<ApplicationEnum> db_menuebuttons__clone = new ArrayList<ApplicationEnum>(db_menuebuttons);// 复制一份
            // 需要删除的菜单按钮
            List<ApplicationEnum> curr_menuebuttons = new ArrayList<ApplicationEnum>(0);
            if (StringUtil.isNotBlank(menuebuttons)) {
                curr_menuebuttons = new ArrayList<ApplicationEnum>(curr_menuebutton.length);
                for (String str : curr_menuebutton) {
                    if (str.indexOf("_") != -1) {
                        ApplicationEnum ap = new ApplicationEnum();
                        ap.setId(str.split("_")[0].trim());
                        ap.setCaption(str.split("_")[1].trim());
                        curr_menuebuttons.add(ap);
                    }
                }
            }
            db_menuebuttons.removeAll(curr_menuebuttons);
            if (!db_menuebuttons.isEmpty()) {
                StringBuffer do_delete = new StringBuffer(" and (");
                hql = "delete from TSysRoleMenuButton where roleid=?";
                for (ApplicationEnum ap : db_menuebuttons) {
                    if (null != ap) {
                        do_delete.append(" (menuid='").append(ap.getId()).append("' and buttonid ='").append(
                                ap.getCaption()).append("') or ");
                    }
                }
                int _s = do_delete.lastIndexOf(" or ");
                if (_s > 0) {
                    do_delete.delete(_s, do_delete.length());
                    do_delete.append(")");
                    hql = hql + do_delete;
                }
                getBaseDao().delete(hql, roleid);
            }
            curr_menuebuttons.removeAll(db_menuebuttons__clone);
            // 剩下的是需要增加的菜单按钮
            if (!curr_menuebuttons.isEmpty()) {

                List<TSysRoleMenuButton> roleMenueButtons = new ArrayList<TSysRoleMenuButton>();
                for (int i = 0; i < curr_menuebuttons.size(); i++) {
                    ApplicationEnum ap = curr_menuebuttons.get(i);
                    TSysRoleMenuButton roleMenuButton = new TSysRoleMenuButton();
                    roleMenuButton.setId(SeqFactory.getNewSequenceAlone());
                    roleMenuButton.setRoleid(roleid);
                    roleMenuButton.setMenuid(ap.getId());
                    roleMenuButton.setButtonid(ap.getCaption());
                    roleMenueButtons.add(roleMenuButton);
                }
                getBaseDao().saveAll(roleMenueButtons);

            }

        }
        action.setParameter("menuebuttons", menuebuttons);
    }

    /**
     * 保存或更新角色菜单
     *
     * @param myaction
     * @param roleid   角色id
     * @param type     操作类型 保存/修改
     * @throws Exception
     */
    public void saveOrUpdateMenu(Object myaction, String roleid, String type) throws Exception {
        BusinessTabButAction action = (BusinessTabButAction) myaction;
        String menues = action.getParameter("menues");
        if (SysConstant.CZLX_XZ.equals(type)) {
            if (menues != null && !menues.equals("") && !menues.equals("000")) {
                // 更新权限表
                menues = menues.replaceAll("000,", "");// 000节点是树的根节点，在权限菜单表中不需要保存

                String[] menues__ = menues.split(",");
                List<TSysRoleMenu> roleMenues = new ArrayList<TSysRoleMenu>();
                for (int i = 0; i < menues__.length; i++) {
                    String o = menues__[i];
                    TSysRoleMenu roleMenu = new TSysRoleMenu();
                    roleMenu.setId(SeqFactory.getNewSequenceAlone());
                    roleMenu.setRoleid(roleid);
                    roleMenu.setMenuid(o.trim());
                    roleMenues.add(roleMenu);
                }
                getBaseDao().saveAll(roleMenues);

            }
        } else {
            // 更新权限菜单表。把数据库中的和用户新提交的菜单比较，采用删除没有的，只添加新增的菜单的策略，提高效率
            menues = menues.replaceAll("000,", "");// 000节点是树的根节点，在权限菜单表中不需要保存

            String hql = "select menuid from TSysRoleMenu where roleid=?";
            List<String> db_menues = getBaseDao().findByHql(hql, roleid);
            if (db_menues != null && !db_menues.isEmpty()) {
                db_menues.remove("000");// 去掉根节点
            } else if (db_menues == null) {
                db_menues = Collections.emptyList();
            }
            List<String> db_menues__clone = new ArrayList<String>(db_menues);// 复制一份
            List<String> curr_menues = new ArrayList<String>(0);
            if (StringUtil.isNotBlank(menues)) {
                Object[] curr_menu = menues.split(",");
                curr_menues = new ArrayList<String>(curr_menu.length);
                for (Object o : curr_menu) {
                    curr_menues.add(o.toString());
                }
            }

            db_menues.removeAll(curr_menues);
            // 剩下的是需要删除的菜单
            if (db_menues.isEmpty() == false) {

                StringBuffer do_menues = new StringBuffer(" and (");
                hql = "delete from TSysRoleMenu where roleid=?";
                for (Object o : db_menues) {
                    if (null != o) {
                        do_menues.append(" menuid='").append(o.toString()).append("' or ");
                    }
                }
                int _s = do_menues.lastIndexOf(" or ");
                if (_s > 0) {
                    do_menues.delete(_s, do_menues.length());
                    do_menues.append(")");
                    hql = hql + do_menues;
                }
                getBaseDao().delete(hql, roleid);
            }

            curr_menues.removeAll(db_menues__clone);
            // 剩下的是需要增加的菜单
            if (!curr_menues.isEmpty()) {
                List<TSysRoleMenu> roleMenues = new ArrayList<TSysRoleMenu>();
                for (int i = 0; i < curr_menues.size(); i++) {
                    String o = curr_menues.get(i);
                    TSysRoleMenu roleMenu = new TSysRoleMenu();
                    roleMenu.setId(SeqFactory.getNewSequenceAlone());
                    roleMenu.setRoleid(roleid);
                    roleMenu.setMenuid(o.trim());
                    roleMenues.add(roleMenu);
                }
                getBaseDao().saveAll(roleMenues);

            }
        }
        action.setParameter("menues", menues);

    }

    /**
     * 通过角色编号，以及接入系统号，将授权信息返回给页面
     *
     * @param obj
     * @param appId
     * @param roleId
     */
    public void getRoleMenu(Object obj, String appId, String roleId) {
        BusinessTabButAction action = (BusinessTabButAction) obj;
        if (StringUtil.isNotBlank(appId) && StringUtil.isNotBlank(roleId)) {
            action.setAppid(appId);//系统号
            /*************开始查询资源角色关系，并将资源编号用逗号分开******************/
            String hql = "select * from t_sys_role_menu t where t.roleid= ? ";
            StringBuilder menuId = new StringBuilder();//资源id
            List<TSysRoleMenu> list = DBUtil.queryAllBeanList(hql, TSysRoleMenu.class, roleId);
            /*************开始保存资源id*************/
            if (null != list && list.size() > 0) {
                int i = 0;//标记循环
                for (TSysRoleMenu tSysRoleMenu : list) {
                    if (0 == i) {
                        menuId.append(tSysRoleMenu.getMenuid());
                    } else {
                        menuId.append("," + tSysRoleMenu.getMenuid());
                    }
                    i++;
                }
                action.setMenuebuttons(menuId.toString());
                action.setMenues(menuId.toString());
                action.setDefaultMenuid(appId);
            } else {
                action.setDefaultMenuid(appId);
            }
            /***************查询并返回部分角色信息******************/
            String hql_role = "select * from t_sys_role t where t.roleid = ? ";
            TSysRole tSysRole = DBUtil.queryBean(hql_role, TSysRole.class, roleId);
            if (null != tSysRole) {
                TSysRole tSysRoleNew = new TSysRole();
                tSysRoleNew.setState(tSysRole.getState());
                tSysRoleNew.setBelongtoapp(tSysRole.getBelongtoapp());
                tSysRoleNew.setBizcode(tSysRole.getBizcode());
                tSysRoleNew.setMemo(tSysRole.getMemo());
                action.setTsysRole(tSysRoleNew);
            }
        }
    }
}
